<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import Popover from './Popover.vue'
import Button from './Button.vue'
import { Clock } from 'lucide-vue-next'
import { cn } from '@/lib/utils'

interface Props {
  modelValue?: string | null
  placeholder?: string
  class?: string
  disabled?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '选择时间',
  modelValue: null
})

const emits = defineEmits<{
  'update:modelValue': [value: string | null]
}>()

const open = ref(false)
const hours = ref('12')
const minutes = ref('00')
const hourScrollRef = ref<HTMLElement | null>(null)
const minuteScrollRef = ref<HTMLElement | null>(null)

// Initialize from modelValue
watch(() => props.modelValue, (val) => {
  if (val) {
    const [h, m] = val.split(':')
    hours.value = h.padStart(2, '0')
    minutes.value = m.padStart(2, '0')
  }
}, { immediate: true })

// 打开弹窗时，初始化滚动位置
watch(open, async (isOpen) => {
  if (isOpen) {
    await nextTick()
    scrollToValue(hourScrollRef.value, hours.value)
    scrollToValue(minuteScrollRef.value, minutes.value)
  }
})

function scrollToValue(container: HTMLElement | null, value: string) {
  if (!container) return
  
  const selectedButton = container.querySelector(`[data-value="${value}"]`) as HTMLElement
  if (!selectedButton) return
  
  const containerHeight = container.clientHeight
  const buttonHeight = selectedButton.offsetHeight
  const buttonTop = selectedButton.offsetTop
  
  // 计算使按钮居中的滚动位置
  const scrollTop = buttonTop - (containerHeight / 2) + (buttonHeight / 2)
  
  container.scrollTo({
    top: scrollTop,
    behavior: 'smooth'
  })
}

// 监听滚动，自动捕捉到中间的选项
function handleScroll(container: HTMLElement, type: 'hour' | 'minute') {
  const containerHeight = container.clientHeight
  const scrollTop = container.scrollTop
  const centerPosition = scrollTop + containerHeight / 2
  
  const buttons = container.querySelectorAll('[data-value]')
  let closestButton: HTMLElement | null = null
  let closestDistance = Infinity
  
  buttons.forEach((button) => {
    const el = button as HTMLElement
    const buttonTop = el.offsetTop
    const buttonHeight = el.offsetHeight
    const buttonCenter = buttonTop + buttonHeight / 2
    const distance = Math.abs(buttonCenter - centerPosition)
    
    if (distance < closestDistance) {
      closestDistance = distance
      closestButton = el
    }
  })
  
  if (closestButton) {
    const value = closestButton.getAttribute('data-value')
    if (value) {
      if (type === 'hour') {
        hours.value = value
      } else {
        minutes.value = value
      }
    }
  }
}

let hourScrollTimer: ReturnType<typeof setTimeout> | null = null
let minuteScrollTimer: ReturnType<typeof setTimeout> | null = null

function onHourScroll() {
  if (!hourScrollRef.value) return
  
  if (hourScrollTimer) clearTimeout(hourScrollTimer)
  
  hourScrollTimer = setTimeout(() => {
    handleScroll(hourScrollRef.value!, 'hour')
    // 滚动结束后，微调到完美居中
    scrollToValue(hourScrollRef.value, hours.value)
  }, 150)
}

function onMinuteScroll() {
  if (!minuteScrollRef.value) return
  
  if (minuteScrollTimer) clearTimeout(minuteScrollTimer)
  
  minuteScrollTimer = setTimeout(() => {
    handleScroll(minuteScrollRef.value!, 'minute')
    // 滚动结束后，微调到完美居中
    scrollToValue(minuteScrollRef.value, minutes.value)
  }, 150)
}

const displayValue = computed(() => {
  return props.modelValue || props.placeholder
})

const hourOptions = Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, '0'))
const minuteOptions = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'))

function handleConfirm() {
  const timeString = `${hours.value}:${minutes.value}`
  emits('update:modelValue', timeString)
  open.value = false
}

function handleClear() {
  emits('update:modelValue', null)
  hours.value = '12'
  minutes.value = '00'
  open.value = false
}
</script>

<template>
  <Popover v-model:open="open" :modal="true">
    <template #trigger>
      <Button
        variant="outline"
        :class="cn(
          'w-full justify-start text-left font-medium',
          !modelValue && 'text-gray-400',
          props.class
        )"
        :disabled="disabled"
      >
        <Clock class="mr-2 h-4 w-4 opacity-70" />
        <span class="text-[13px]">{{ displayValue }}</span>
      </Button>
    </template>
    <div class="macos-time-picker-panel">
      <div class="macos-time-picker-selectors">
        <!-- 小时选择器 -->
        <div class="macos-time-picker-column">
          <label class="macos-time-picker-label">小时</label>
          <div class="macos-time-picker-scroll-wrapper">
            <div 
              ref="hourScrollRef"
              class="macos-time-picker-scroll"
              @scroll="onHourScroll"
            >
              <div class="macos-time-picker-padding"></div>
              <button
                v-for="h in hourOptions"
                :key="h"
                type="button"
                :data-value="h"
                :class="[
                  'macos-time-picker-option',
                  hours === h && 'macos-time-picker-option-selected'
                ]"
                @click="() => { hours = h; scrollToValue(hourScrollRef, h) }"
              >
                {{ h }}
              </button>
              <div class="macos-time-picker-padding"></div>
            </div>
            <div class="macos-time-picker-indicator"></div>
            <div class="macos-time-picker-fade macos-time-picker-fade-top"></div>
            <div class="macos-time-picker-fade macos-time-picker-fade-bottom"></div>
          </div>
        </div>
        
        <div class="macos-time-picker-separator">:</div>
        
        <!-- 分钟选择器 -->
        <div class="macos-time-picker-column">
          <label class="macos-time-picker-label">分钟</label>
          <div class="macos-time-picker-scroll-wrapper">
            <div 
              ref="minuteScrollRef"
              class="macos-time-picker-scroll"
              @scroll="onMinuteScroll"
            >
              <div class="macos-time-picker-padding"></div>
              <button
                v-for="m in minuteOptions"
                :key="m"
                type="button"
                :data-value="m"
                :class="[
                  'macos-time-picker-option',
                  minutes === m && 'macos-time-picker-option-selected'
                ]"
                @click="() => { minutes = m; scrollToValue(minuteScrollRef, m) }"
              >
                {{ m }}
              </button>
              <div class="macos-time-picker-padding"></div>
            </div>
            <div class="macos-time-picker-indicator"></div>
            <div class="macos-time-picker-fade macos-time-picker-fade-top"></div>
            <div class="macos-time-picker-fade macos-time-picker-fade-bottom"></div>
          </div>
        </div>
      </div>
      
      <div class="macos-time-picker-actions">
        <Button variant="outline" size="sm" @click="handleClear">
          清除
        </Button>
        <Button size="sm" @click="handleConfirm">
          确定
        </Button>
      </div>
    </div>
  </Popover>
</template>

